package com.lijian.community.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.lijian.community.dto.CommentDTO;
import com.lijian.community.enums.CommentTypeEnum;
import com.lijian.community.enums.NoticeStatusEnum;
import com.lijian.community.enums.NoticeTypeEnum;
import com.lijian.community.exception.CustomizeErrorCode;
import com.lijian.community.exception.CustomizeException;
import com.lijian.community.mapper.CommentMapper;
import com.lijian.community.mapper.NoticeMapper;
import com.lijian.community.mapper.QuestionMapper;
import com.lijian.community.mapper.UserMapper;
import com.lijian.community.model.Comment;
import com.lijian.community.model.Notice;
import com.lijian.community.model.Question;
import com.lijian.community.model.User;
import com.lijian.community.service.CommentService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

@Service
public class CommentServiceImpl implements CommentService {

    @Autowired
    private QuestionMapper questionMapper;

    @Autowired
    private CommentMapper commentMapper;

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private NoticeMapper noticeMapper;

    @Override
    @Transactional
    public void addComment(Comment comment, User commentator) {
        if (comment.getQuestionId() == null || comment.getQuestionId() == 0) {
            throw new CustomizeException(CustomizeErrorCode.TARGET_PARAM_NOT_FOUND);
        }
        if (comment.getType() == null || !CommentTypeEnum.isExist(comment.getType())) {
            throw new CustomizeException(CustomizeErrorCode.TYPE_PARAM_WRONG);
        }
        //type=1是评论，否则是回复问题
        if (comment.getType() == CommentTypeEnum.COMMENT.getType()) {
            //回复评论
            Comment dbComment = commentMapper.selectById(comment.getQuestionId());
            if (dbComment == null) {
                throw new CustomizeException(CustomizeErrorCode.COMMENT_NOT_FOUND);
            }

            //回复问题
            Question question = questionMapper.selectById(dbComment.getQuestionId());
            if (question == null) {
                throw new CustomizeException(CustomizeErrorCode.QUESTION_NOT_FOUND);
            }
            commentMapper.insert(comment);

            //添加通知
            addNotice(comment, dbComment.getUserId(), commentator.getName(), question.getTitle(), NoticeTypeEnum.REPLY_COMMENT, question.getId());
        } else {
            //回复问题
            Question question = questionMapper.selectById(comment.getQuestionId());
            if (question == null) {
                throw new CustomizeException(CustomizeErrorCode.QUESTION_NOT_FOUND);
            }
            commentMapper.insert(comment);
            //评论成功后，回复数 + 1
            questionMapper.updateComment(comment.getQuestionId());

            //添加通知
            addNotice(comment, question.getCreator(), commentator.getName(), question.getTitle(), NoticeTypeEnum.REPLY_QUESTION, question.getId());
        }
    }

    private void addNotice(Comment comment, Integer receiver, String notifierName, String outerTitle, NoticeTypeEnum NoticeType, Integer outerId) {
        //如果评论是自己写的，不需要通知
        if (receiver == comment.getUserId()) {
            return;
        }
        Notice notice = new Notice();
        notice.setCreateTime(new Date());
        notice.setType(NoticeType.getType());
        notice.setOuterId(outerId);
        notice.setUserNotifier(comment.getUserId());
        notice.setUserReceiver(receiver);
        notice.setStatus(NoticeStatusEnum.UNREAD.getStatus());
        notice.setNotifierName(notifierName);
        notice.setOuterTitle(outerTitle);
        noticeMapper.insert(notice);
    }

    @Override
    public List<CommentDTO> findListTargetById(Integer id, CommentTypeEnum type) {
        QueryWrapper<Comment> commentQueryWrapper = new QueryWrapper<>();
        commentQueryWrapper.eq("question_id", id);
        commentQueryWrapper.eq("type", type.getType());
        commentQueryWrapper.orderByDesc("create_time");
        List<Comment> commentList = commentMapper.selectList(commentQueryWrapper);
        if (commentList.size() == 0) {
            return null;
        }
        //使用去重的评论人（用户）
        Set<Integer> commentUser = commentList.stream()
                .map(comment -> comment.getUserId()).collect(Collectors.toSet());

        List<Integer> userIds = new ArrayList<>();
        userIds.addAll(commentUser);
        //获取评论人，并且转换为map
        List<User> userList = userMapper.selectBatchIds(userIds);
        Map<Integer, User> userMap = userList.stream().collect(Collectors.toMap(user -> user.getId(), user -> user));
        //转换comment 为 commentDTO
        List<CommentDTO> commentDTOList = commentList.stream().map(comment -> {
            CommentDTO commentDTO = new CommentDTO();
            BeanUtils.copyProperties(comment, commentDTO);
            commentDTO.setUser(userMap.get(comment.getUserId()));
            return commentDTO;
        }).collect(Collectors.toList());

        return commentDTOList;
    }

    @Override
    public void incCommentCount(Integer id) {
        commentMapper.updateCommentCount(id);
    }
}